home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / Sample Code / Sample Editors⁄Viewers / Draw Editor / Source / Shapes.cpp < prev    next >
Encoding:
Text File  |  1995-12-11  |  76.8 KB  |  2,616 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        Shapes.cpp
  3.  
  4.     Contains:    Shape Classes Implementation
  5.  
  6.     Written by:    Dave Stafford
  7.     
  8.     Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  9. */
  10.  
  11. // -- DrawEditor Includes --
  12.  
  13. #ifndef _COMPILERDEFS_
  14. #include "CompDefs.h"
  15. #endif
  16.  
  17. #ifndef _DRAWEDITORUTILS_
  18. #include "DrawEditorUtils.h"
  19. #endif
  20.  
  21. #ifndef _SHAPES_
  22. #include "Shapes.h"
  23. #endif
  24.  
  25. #ifndef _FRAMEPROXY_
  26. #include "FrameProxy.h"
  27. #endif
  28.  
  29. #ifndef _DRAWEDITOR_
  30. #include "DrawEditor.h"
  31. #endif
  32.  
  33. #ifndef _LINK_
  34. #include "Link.h"
  35. #endif
  36.  
  37. #ifndef _DRAWEDITORGLOBALS_
  38. #include "DrawEditorGlobals.h"
  39. #endif
  40.  
  41. // -- OpenDoc Includes --
  42.  
  43. #ifndef SOM_ODShape_xh
  44. #include <Shape.xh>
  45. #endif
  46.  
  47. #ifndef SOM_ODFacet_xh
  48. #include <Facet.xh>
  49. #endif
  50.  
  51. #ifndef SOM_ODFacetIterator_xh
  52. #include <FacetItr.xh>
  53. #endif
  54.  
  55. #ifndef SOM_ODFrame_xh
  56. #include <Frame.xh>
  57. #endif
  58.  
  59. #ifndef SOM_ODFrameFacetIterator_xh
  60. #include <FrFaItr.xh>
  61. #endif
  62.  
  63. #ifndef SOM_ODWindow_xh
  64. #include <Window.xh>
  65. #endif
  66.  
  67. #ifndef SOM_ODStorageUnit_xh
  68. #include <StorageU.xh>
  69. #endif
  70.  
  71. #ifndef SOM_ODSession_xh
  72. #include <ODSessn.xh>
  73. #endif
  74.  
  75. #ifndef SOM_ODPart_xh
  76. #include <Part.xh>
  77. #endif
  78.  
  79. // -- OpenDoc Utilities --
  80.  
  81. #ifndef _TEMPOBJ_
  82. #include "TempObj.h"
  83. #endif
  84.  
  85. #ifndef _ODUTILS_
  86. #include "ODUtils.h"
  87. #endif
  88.  
  89. #ifndef _USERSRCM_
  90. #include "UseRsrcM.h"            // allow access to our library's resource fork
  91. #endif
  92.  
  93. #ifndef _ODMEMORY_
  94. #include "ODMemory.h"            // ODDisposePtr
  95. #endif
  96.  
  97. #ifndef _FOCUSLIB_
  98. #include <FocusLib.h>
  99. #endif
  100.  
  101. #ifndef _STORUTIL_
  102. #include <StorUtil.h>
  103. #endif
  104.  
  105. #ifndef _ORDCOLL_
  106. #include "OrdColl.h"
  107. #endif
  108.  
  109. #ifndef _ODDEBUG_
  110. #include "ODDebug.h"
  111. #endif
  112.  
  113. #ifndef _UTILERRS_
  114. #include "UtilErrs.h"
  115. #endif
  116.  
  117. // -- Toolbox Includes --
  118.  
  119. #ifndef mathRoutinesIncludes
  120. #include <math routines.h>
  121. #endif
  122.  
  123. /*----------------------------------------------------------------------------------------
  124.  Notes:
  125.  
  126. • MovedFirst, MovedForward, MovedLast, MovedBackWard, are notifications that
  127. the given actions have occured, they should not be called to effect the change their
  128. names imply.
  129. • Added RemovedShape & RestoredShape. These are essentially for the proxy derivatives of shape.
  130.   Removed & Restore shape should be called by commands that do this. The commands should tell
  131.   the part to add/remove the shape ( not tell the shape to add itself to the part, like OPFDraw )
  132.   Then, the part should notify the shape that the action has occured so it can adjust itself 
  133.   accordingly.
  134. ----------------------------------------------------------------------------------------*/
  135.  
  136.  
  137. // **************************** Need to improve Handling of Failure **********************
  138.  
  139. //=============================================================================
  140. // class CShape
  141. //=============================================================================
  142.  
  143. //------------------------------------------------------------------------------
  144. // CShape::CShape
  145. //------------------------------------------------------------------------------
  146.  
  147. CShape::CShape(ODSShort numberOfHandles, ODSShort shapeType)
  148. {
  149.     fRect = gGlobals->fZeroRect;
  150.     fShapeType = shapeType;
  151.     fNumberOfHandles = numberOfHandles;
  152.     fSelected = kODFalse;
  153.     fPromisedToClipboard = kODFalse;
  154.     
  155.     fColor = (*gGlobals->fBlackColor);
  156.     fCanDrawColor = kODTrue;
  157.     fShown = kODTrue;
  158.     
  159.     fPublishLinks = new COrderedList;  //(MH)
  160.     fSubscribeLink = kODNULL;
  161.     
  162.     fExternalizationIndex = 0;
  163.     
  164. }
  165.  
  166.  
  167. //------------------------------------------------------------------------------
  168. // CShape::~CShape
  169. //------------------------------------------------------------------------------
  170.  
  171. CShape::~CShape()
  172. {
  173.     if (fPublishLinks)
  174.         delete fPublishLinks;
  175. }
  176.  
  177.  
  178. //------------------------------------------------------------------------------
  179. // CShape::IsPromisedToClipboard
  180. //------------------------------------------------------------------------------
  181.  
  182. ODBoolean CShape::IsPromisedToClipboard() const
  183. {
  184.     return fPromisedToClipboard;
  185. }
  186.  
  187. //------------------------------------------------------------------------------
  188. // CShape::SetPromisedToClipboard
  189. //------------------------------------------------------------------------------
  190.  
  191. void CShape::SetPromisedToClipboard(ODBoolean promised)
  192. {
  193.     fPromisedToClipboard = promised;
  194. }
  195.  
  196. //------------------------------------------------------------------------------
  197. // CShape::GetShapeType
  198. //------------------------------------------------------------------------------
  199.  
  200. ODSShort CShape::GetShapeType() const
  201. {
  202.     return fShapeType;
  203. }
  204.  
  205. //------------------------------------------------------------------------------
  206. // CShape::SetCanDrawColor
  207. //------------------------------------------------------------------------------
  208.  
  209. void CShape::SetCanDrawColor(ODBoolean toggle)
  210. {
  211.     fCanDrawColor = toggle;
  212. }
  213.  
  214. //------------------------------------------------------------------------------
  215. // CShape::GetCanDrawColor
  216. //------------------------------------------------------------------------------
  217.  
  218. ODBoolean CShape::GetCanDrawColor()
  219. {
  220.     return fCanDrawColor;
  221. }
  222.  
  223. //------------------------------------------------------------------------------
  224. // CShape::SetColor
  225. //------------------------------------------------------------------------------
  226.  
  227. void CShape::SetColor(const CRGBColor& color)
  228. {
  229.     fColor = color;
  230. }
  231.  
  232. //------------------------------------------------------------------------------
  233. // CShape::GetColor
  234. //------------------------------------------------------------------------------
  235.  
  236. CRGBColor* CShape::GetColor()
  237. {
  238.     return &fColor;
  239. }
  240.  
  241. //------------------------------------------------------------------------------
  242. // CRectangleShape::Show
  243. //------------------------------------------------------------------------------
  244. void CShape::Show(Environment* ev, ODBoolean show)
  245. {
  246.     fShown = show;            
  247. }
  248.  
  249. //------------------------------------------------------------------------------
  250. // CRectangleShape::IsShown
  251. //------------------------------------------------------------------------------
  252. ODBoolean CShape::IsShown()
  253. {
  254.     return fShown;            
  255. }
  256.  
  257.  
  258. //------------------------------------------------------------------------------
  259. // CShape::Draw
  260. //------------------------------------------------------------------------------
  261.  
  262. void CShape::DrawShape(Environment* ev, ODFacet* facet)
  263. {
  264.     if (IsSelected()&&IsShown())
  265.         DrawHandles();
  266. }
  267.  
  268.  
  269. //------------------------------------------------------------------------------
  270. // CShape::GetUpdateShape
  271. //------------------------------------------------------------------------------
  272.  
  273. void CShape::GetUpdateShape(Environment* ev, ODShape* updateShape) const
  274. {
  275.     ODRect bounds(fRect);
  276.     bounds.left -= fl(2.5); 
  277.     bounds.top -= fl(2.5);
  278.     bounds.right += fl(2.5);
  279.     bounds.bottom += fl(2.5);
  280.     updateShape->SetRectangle(ev, &bounds);
  281. }
  282.  
  283.  
  284. //------------------------------------------------------------------------------
  285. // CShape::GetUpdateBox
  286. //------------------------------------------------------------------------------
  287.  
  288. void CShape::GetUpdateBox(Environment* ev, ODRect* updateBox) const
  289. {
  290.     ODRect bounds(fRect);
  291.     updateBox->left -= fl(2.5);
  292.     updateBox->top -= fl(2.5);
  293.     updateBox->right += fl(2.5);
  294.     updateBox->bottom += fl(2.5);
  295. }
  296.  
  297.  
  298. //------------------------------------------------------------------------------
  299. // CShape::GetBoundingRegion
  300. //------------------------------------------------------------------------------
  301.  
  302. ODRgnHandle CShape::GetBoundingRegion() const
  303. {
  304.     ODRgnHandle tRegion = NewRgn();
  305.     THROW_IF_NULL(tRegion);
  306.     
  307.     RectRgn(tRegion, &fRect);
  308.     
  309.     return tRegion;
  310. }
  311.  
  312.  
  313. //------------------------------------------------------------------------------
  314. // CShape::GetBoundingBox
  315. //------------------------------------------------------------------------------
  316.  
  317. void CShape::GetBoundingBox(Rect* bounds) const
  318. {
  319.     *bounds = fRect;
  320. }
  321.  
  322.  
  323. //------------------------------------------------------------------------------
  324. // CShape::GetBoundingBox
  325. //------------------------------------------------------------------------------
  326.  
  327. void CShape::GetBoundingBox(ODRect* bounds) const
  328. {
  329.     *bounds = fRect;
  330. }
  331.  
  332.  
  333. //------------------------------------------------------------------------------
  334. // CShape::SetBoundingBox
  335. //------------------------------------------------------------------------------
  336.  
  337. void CShape::SetBoundingBox(Environment* ev, const Rect& bounds)
  338. {
  339.     fRect = bounds;
  340. }
  341.  
  342.  
  343. //------------------------------------------------------------------------------
  344. // CShape::SetBoundingBox
  345. //------------------------------------------------------------------------------
  346.  
  347. void CShape::SetBoundingBox(Environment* ev, ODShape* bounds)
  348. {
  349.     THROW_IF_NULL(bounds);
  350.     
  351.     ODRgnHandle tRegion = bounds->GetQDRegion(ev);
  352.     Rect tRect = (*tRegion)->rgnBBox;
  353.     
  354.     this->SetBoundingBox(ev, tRect);
  355. }
  356.  
  357.  
  358. //------------------------------------------------------------------------------
  359. // CShape::SetBoundingBox
  360. //------------------------------------------------------------------------------
  361.  
  362. void CShape::SetBoundingBox(Environment* ev, const Point& anchorPoint,  const Point& currentPoint)
  363. {
  364.     if (anchorPoint.h < currentPoint.v)
  365.     {
  366.         fRect.left = anchorPoint.h;
  367.         fRect.right = currentPoint.h;
  368.     }
  369.     else
  370.     {
  371.         fRect.left = currentPoint.h;
  372.         fRect.right = anchorPoint.h;
  373.     }
  374.     
  375.     if (anchorPoint.v < currentPoint.v)
  376.     {
  377.         fRect.top = anchorPoint.v;
  378.         fRect.bottom = currentPoint.v;
  379.     }
  380.     else
  381.     {
  382.         fRect.top = currentPoint.v;
  383.         fRect.bottom = anchorPoint.v;
  384.     }
  385. }
  386.  
  387. //------------------------------------------------------------------------------
  388. // CShape::ContainsProxyForFrame
  389. //
  390. // This method should return kODTrue if the given frame is embedded within this
  391. // item of content. 
  392. //------------------------------------------------------------------------------
  393.  
  394. ODBoolean CShape::ContainsProxyForFrame(Environment* ev, ODFrame* frame)
  395. {
  396.     // CShapes cannot represent embedded content, so alway return kODFalse
  397.     return kODFalse;
  398. }
  399.  
  400.  
  401. //------------------------------------------------------------------------------
  402. // CShape::SetInLimbo
  403. //
  404. //------------------------------------------------------------------------------
  405.  
  406. void CShape::SetInLimbo(Environment* ev, ODBoolean isInLimbo)
  407. {
  408.     // Limbo is an embedded frame issue, do nothing here.
  409. }
  410.  
  411.  
  412. //------------------------------------------------------------------------------
  413. // CShape::OffsetShape
  414. //------------------------------------------------------------------------------
  415.  
  416. void CShape::OffsetShape(Environment* ev, ODCoordinate xDelta, ODCoordinate yDelta)
  417. {
  418.     ::OffsetRect( &fRect, FixedToInt(xDelta), FixedToInt(yDelta) );
  419. }
  420.  
  421. //------------------------------------------------------------------------------
  422. // CShape::GetHandleCenter
  423. //------------------------------------------------------------------------------
  424.  
  425. void CShape::GetHandleCenter(short whichHandle, Point* center) const
  426. {    
  427.     switch (whichHandle)
  428.     {
  429.         case kInTopLeftCorner:
  430.             center->h = fRect.left;
  431.             center->v = fRect.top;
  432.             break;
  433.         case kInTopRightCorner:
  434.             center->h = fRect.right;
  435.             center->v = fRect.top;
  436.             break;
  437.         case kInBottomLeftCorner:
  438.             center->h = fRect.left;
  439.             center->v = fRect.bottom;
  440.             break;
  441.         case kInBottomRightCorner:
  442.             center->h = fRect.right;
  443.             center->v = fRect.bottom;
  444.             break;
  445.     }
  446. }
  447.  
  448. //------------------------------------------------------------------------------
  449. // CShape::CalcHandle
  450. //------------------------------------------------------------------------------
  451.  
  452. void CShape::CalcHandle(short whichHandle, Rect* bounds) const
  453. {
  454.     Point pt;
  455.     GetHandleCenter(whichHandle, &pt);
  456.     
  457.     bounds->top = pt.v - 2;
  458.     bounds->left = pt.h - 2;
  459.     bounds->bottom = pt.v + 2;
  460.     bounds->right = pt.h + 2;
  461. }
  462.  
  463.  
  464. //------------------------------------------------------------------------------
  465. // CShape::DrawHandles
  466. //------------------------------------------------------------------------------
  467.  
  468. void CShape::DrawHandles()
  469. {
  470.     Rect handleRect;
  471.     
  472.     // Save the Pen
  473.     PenState tPen;
  474.     RGBColor tColor;
  475.     GetPenState(&tPen);
  476.     GetForeColor(&tColor);
  477.     
  478.     // Set the color
  479.     RGBForeColor((RGBColor*)&gGlobals->fBlackColor);
  480.     
  481.     for (short i=1; i<=fNumberOfHandles; i++)
  482.     {
  483.         CalcHandle(i, &handleRect);    
  484.         PaintRect(&handleRect);
  485.     }
  486.  
  487.     // Restore state
  488.     RGBForeColor(&tColor);
  489.     SetPenState(&tPen);
  490.  
  491. }
  492.  
  493.  
  494. //------------------------------------------------------------------------------
  495. // CShape::ShapeInRectangle
  496. //------------------------------------------------------------------------------
  497.  
  498. ODBoolean CShape::ShapeInRectangle(const Rect& rect) const
  499. {
  500.     Rect bounds;
  501.     GetBoundingBox(&bounds);
  502.     
  503.     Rect intersection;
  504.     SectRect(&bounds, &rect, &intersection);
  505.     
  506.     // If the Intersection is equal to the bounds
  507.     // then we are fully contained by the given rectangle.
  508.     return EqualRect(&bounds,&intersection);
  509. }
  510.  
  511.  
  512. //------------------------------------------------------------------------------
  513. // CShape::SelectShape
  514. //------------------------------------------------------------------------------
  515.  
  516. void CShape::SelectShape(Environment* ev, ODBoolean state)
  517. {
  518.     ASSERT(fSelected != state, kODErrAssertionFailed);
  519.     
  520.     fSelected = state;
  521.     
  522.     COrderedList* pubLinks;
  523.     
  524.     if (fSubscribeLink)
  525.     {
  526.         fSubscribeLink->ShapeSelected(state);
  527.         pubLinks = fSubscribeLink->GetPublishLinks();
  528.     }
  529.     else
  530.     {
  531.         pubLinks = fPublishLinks;
  532.     }
  533.  
  534.     COrdListIterator linkIte(pubLinks);
  535.     for (CPublishLink* pLink = (CPublishLink*)linkIte.First(); linkIte.IsNotComplete(); pLink = (CPublishLink*)linkIte.Next())
  536.     {
  537.         pLink->ShapeSelected(state);
  538.     }
  539. }
  540.  
  541.  
  542. //------------------------------------------------------------------------------
  543. // CShape::WhichHandle
  544. //------------------------------------------------------------------------------
  545.  
  546. ODSShort CShape::WhichHandle(const Point& mouse) const
  547. {
  548.     Rect handleRect;
  549.     for (short i=1; i<=fNumberOfHandles; i++)
  550.     {
  551.         CalcHandle( i, &handleRect );
  552.         if (::PtInRect(mouse, &handleRect))
  553.             return i;
  554.     }
  555.         
  556.     return 0;
  557. }
  558.  
  559.  
  560. //------------------------------------------------------------------------------
  561. // CShape::GetDragRect
  562. //------------------------------------------------------------------------------
  563.  
  564. void CShape::GetDragRect(Rect* dragRect) const
  565. {
  566.     GetBoundingBox(dragRect);
  567. }
  568.  
  569.  
  570. //------------------------------------------------------------------------------
  571. // CShape::CreateDragShape
  572. // Be sure to release the shape returned from this call
  573. //------------------------------------------------------------------------------
  574.  
  575. ODShape* CShape::CreateDragShape(Environment *ev, ODFacet* facet)
  576. {
  577.     ODRect bounds(fRect);
  578.         
  579.     ODShape* dragRgn = facet->CreateShape(ev);    
  580.     dragRgn->SetRectangle(ev, &bounds);
  581.     
  582.     bounds.Inset(ff(1), ff(1));
  583.     
  584.     ODShape* donutHole = facet->CreateShape(ev);    
  585.     donutHole->SetRectangle(ev, &bounds);
  586.     
  587.     dragRgn->Subtract(ev, donutHole);
  588.     ODReleaseObject(ev, donutHole);
  589.     
  590.     return dragRgn;
  591. }
  592.  
  593.  
  594. //------------------------------------------------------------------------------
  595. // CShape::InvalidateHandles
  596. // Be sure to release the shape returned from this call
  597. //------------------------------------------------------------------------------
  598.  
  599. void CShape::InvalidateHandles(Environment *ev, ODFrame* frame)
  600. {
  601.     ODRect bounds(fRect);
  602.         
  603.     // Invalidate all the shape handles
  604.     Rect handleRect;
  605.     ODShape* tShape = frame->CreateShape(ev);
  606.     
  607.     for (short i=1; i<=fNumberOfHandles; i++)
  608.     {
  609.         CalcHandle(i, &handleRect);    
  610.         ODRect handle(handleRect);
  611.         tShape->SetRectangle(ev, &handle);
  612.         
  613.         frame->Invalidate(ev, tShape, kODNULL);
  614.     }
  615.     
  616. }
  617.  
  618.  
  619. //------------------------------------------------------------------------------
  620. // CShape::ResizeFeedback
  621. //------------------------------------------------------------------------------
  622.  
  623. void CShape::ResizeFeedback(ODFacet* facet, short whichHandle, Point& mouseLoc, ODBoolean draw)
  624. {
  625.     Rect srcRect, dstRect;
  626.     GetResizeRect(whichHandle, mouseLoc, &srcRect, &dstRect);
  627.     SortRect(&dstRect);
  628.     OutlineShape(facet, dstRect, draw);
  629. }
  630.  
  631.  
  632. //------------------------------------------------------------------------------
  633. // CShape::Resize
  634. //------------------------------------------------------------------------------
  635.  
  636. void CShape::Resize(Environment *ev, Rect& baseRect, Rect& resizeRect)
  637. {
  638.     MapRect(baseRect, resizeRect, &fRect);
  639. }
  640. //------------------------------------------------------------------------------
  641. // CShape::GetResizeRect
  642. //------------------------------------------------------------------------------
  643. void CShape::GetResizeRect(ODSShort whichHandle, Point& mouseLoc, Rect* srcRect, Rect* dstRect)
  644. {
  645.     *srcRect = fRect;
  646.     *dstRect = *srcRect;
  647.     
  648.     switch (whichHandle)
  649.     {
  650.         case kInTopLeftCorner:
  651.             dstRect->left = mouseLoc.h;
  652.             dstRect->top = mouseLoc.v;
  653.             break;
  654.         case kInTopRightCorner:
  655.             dstRect->right = mouseLoc.h;
  656.             dstRect->top = mouseLoc.v;
  657.             break;
  658.         case kInBottomLeftCorner:
  659.             dstRect->left = mouseLoc.h;
  660.             dstRect->bottom = mouseLoc.v;
  661.             break;
  662.         case kInBottomRightCorner:
  663.             dstRect->right = mouseLoc.h;
  664.             dstRect->bottom = mouseLoc.v;
  665.             break;
  666.     }
  667. }
  668.  
  669. //------------------------------------------------------------------------------
  670. // CEmbeddingShape::Activate
  671. //
  672. // Description:    
  673. // Nothing is done here, Embedding shapes will override.
  674. //------------------------------------------------------------------------------
  675.  
  676. void CShape::Activate(Environment* ev, ODBoolean activating, ODFrame* frame)
  677. {
  678.     
  679. }
  680.  
  681. //------------------------------------------------------------------------------
  682. // CShape::MoveAfter
  683. // This method is called to move 'this' shape after the given one.
  684. // Nothing is done here, Embedding shapes will override.
  685. //------------------------------------------------------------------------------
  686. void CShape::MoveAfter(Environment* ev, CShape* shape)
  687. {
  688.     
  689. }
  690.  
  691. //------------------------------------------------------------------------------
  692. // CShape::MoveBefore
  693. // This method is called to move 'this' shape before the given one.
  694. // Nothing is done here, Embedding shapes will override.
  695. //------------------------------------------------------------------------------
  696. void CShape::MoveBefore(Environment* ev, CShape* shape)
  697. {
  698. }
  699.  
  700.  
  701. //------------------------------------------------------------------------------
  702. // CShape::IsFrozen
  703. // This will probably be only overridden by the proxy derivatives of shape
  704. // Nothing is done here, Embedding shapes will override.
  705. //------------------------------------------------------------------------------
  706.  
  707. ODBoolean CShape::IsFrozen() const
  708. {
  709.     return kODFalse;
  710. }
  711.  
  712. //------------------------------------------------------------------------------
  713. // CShape::SetFrozen
  714. // This method is called after the action has completed.
  715. // This will probably be only overridden by the Embedding derivatives of shape
  716. //------------------------------------------------------------------------------
  717. ODBoolean CShape::SetFrozen(ODBoolean state)
  718. {
  719. UNUSED(state);
  720.     return kODFalse;    // Means I don't care
  721. }
  722.  
  723. //------------------------------------------------------------------------------
  724. // CShape::Added
  725. // This method is called after the action has completed.
  726. // This will probably be only overridden by the Embedding derivatives of shape.
  727. //------------------------------------------------------------------------------
  728. void CShape::Added(Environment *ev)
  729. {
  730.     if(fSubscribeLink)
  731.         fSubscribeLink->AddShape(this);
  732.     else
  733.     {
  734.         COrdListIterator ite(fPublishLinks);
  735.         for (CPublishLink* plink = (CPublishLink*)ite.First(); ite.IsNotComplete(); plink = (CPublishLink*)ite.Next())
  736.             plink->AddShape(this);
  737.     }
  738.         
  739. }
  740.  
  741. //------------------------------------------------------------------------------
  742. // CShape::Removed
  743. // This method is called after the action has completed.
  744. // This will probably be only overridden by the proxy derivatives of shape.
  745. //------------------------------------------------------------------------------
  746. void CShape::Removed(Environment* ev, ODBoolean commit)
  747. {
  748.     if(fSubscribeLink)
  749.         fSubscribeLink->RemoveShape(this);
  750.     else
  751.     {
  752.         COrdListIterator ite(fPublishLinks);
  753.         for (CPublishLink* plink = (CPublishLink*)ite.First(); ite.IsNotComplete(); plink = (CPublishLink*)ite.Next())
  754.             plink->RemoveShape(this);
  755.         
  756.     }
  757.         
  758. }
  759.  
  760. //----------------------------------------------------------------------------------------
  761. // CShape::Open
  762. //
  763. // This method is called by the part when the user has selected "Open" for a selection.
  764. // This will probably be only overridden by the proxy derivatives of shape.
  765. //----------------------------------------------------------------------------------------
  766. void CShape::Open(Environment *ev, ODFrame* container)
  767. {
  768. }
  769.  
  770.  
  771. //----------------------------------------------------------------------------------------
  772. // CShape::DisplayFrameConnected
  773. //
  774. // This method is called by the part when a display frame is added for the first time.
  775. // This will probably be only overridden by the proxy derivatives of shape.
  776. //----------------------------------------------------------------------------------------
  777. void CShape::DisplayFrameConnected(Environment *ev, ODFrame* frame)
  778. {
  779. }
  780.  
  781.  
  782. //----------------------------------------------------------------------------------------
  783. // CShape::DisplayFrameAdded
  784. //
  785. // This method is called by the part when a display frame is added for the first time.
  786. // This will probably be only overridden by the proxy derivatives of shape.
  787. //----------------------------------------------------------------------------------------
  788. void CShape::DisplayFrameAdded(Environment *ev, ODFrame* frame)
  789. {
  790. }
  791.  
  792.  
  793. //----------------------------------------------------------------------------------------
  794. // CShape::DisplayFrameRemoved
  795. //
  796. // This method is called by the part when a display frame is removed.
  797. // This will probably be only overridden by the proxy derivatives of shape.
  798. //----------------------------------------------------------------------------------------
  799. void CShape::DisplayFrameRemoved(Environment *ev, ODFrame* frame)
  800. {
  801. }
  802.  
  803.  
  804. //----------------------------------------------------------------------------------------
  805. // CShape::Dragging
  806. //
  807. // This method is called by the part when a the user is dragging this shape.
  808. // This will probably be only overridden by the proxy derivatives of shape.
  809. //----------------------------------------------------------------------------------------
  810. void CShape::Dragging(Environment *ev, ODBoolean dragging)
  811. {
  812. }
  813.  
  814.  
  815. //----------------------------------------------------------------------------------------
  816. // CShape::FacetAdded
  817. //
  818. // This method is called by the part when a new containing facet is added.
  819. // This will probably be only overridden by the proxy derivatives of shape.
  820. //----------------------------------------------------------------------------------------
  821. void CShape::FacetAdded(Environment *ev, ODFacet* facet)
  822. {
  823. }
  824.  
  825.  
  826. //----------------------------------------------------------------------------------------
  827. // CEmbeddingShape::DisplayFrameClosed
  828. //
  829. // This method is called by the part when a display frame is removed.
  830. // This will probably be only overridden by the proxy derivatives of shape.
  831. //----------------------------------------------------------------------------------------
  832. void CShape::DisplayFrameClosed(Environment *ev, ODFrame* frame)
  833. {
  834. }
  835.  
  836.  
  837.  
  838. //----------------------------------------------------------------------------------------
  839. // CShape::FacetRemoved
  840. //
  841. // This method is called by the part when a containing facet is removed.
  842. // This will probably be only overridden by the proxy derivatives of shape.
  843. //----------------------------------------------------------------------------------------
  844. void CShape::FacetRemoved(Environment *ev, ODFacet* facet)
  845. {
  846. }
  847.  
  848. //------------------------------------------------------------------------------
  849. // CShape::Read
  850. // We assume that the storage unit is focused to a property and value and
  851. // that the current offset is the beginning of a shape.
  852. //------------------------------------------------------------------------------
  853. void CShape::Read(Environment* ev, ODStorageUnitView* view, CCloneInfo* cloneInfo)
  854. {
  855.     UNUSED(cloneInfo);
  856.     
  857.     TRY
  858.         // Get the rectangle
  859.         StorageUnitViewGetValue(view, ev, sizeof(Rect), &fRect);
  860.         
  861.         // Get the shape type
  862.         StorageUnitViewGetValue(view, ev, sizeof(ODSShort), &fShapeType);
  863.         
  864.         // Get the number of handles
  865.         StorageUnitViewGetValue(view, ev, sizeof(ODSShort), &fNumberOfHandles);
  866.     
  867.         // Get the shape color
  868.         StorageUnitViewGetValue(view, ev, sizeof(CRGBColor), &fColor);
  869.     
  870.     ENDTRY
  871. }
  872.  
  873.  
  874. //------------------------------------------------------------------------------
  875. // CShape::Read
  876. // We assume that the storage unit is focused to a property and value and
  877. // that the current offset is the beginning of a shape.
  878. //------------------------------------------------------------------------------
  879. void CShape::Read(Environment* ev, ODStorageUnit* storage, CCloneInfo* cloneInfo)
  880. {
  881.     UNUSED(cloneInfo);
  882.  
  883.     TRY
  884.         // Get the rectangle
  885.         StorageUnitGetValue(storage, ev, sizeof(Rect), &fRect);
  886.         
  887.         // Get the shape type
  888.         StorageUnitGetValue(storage, ev, sizeof(ODSShort), &fShapeType);
  889.         
  890.         // Get the number of handles
  891.         StorageUnitGetValue(storage, ev, sizeof(ODSShort), &fNumberOfHandles);
  892.     
  893.         // Get the shape color
  894.         StorageUnitGetValue(storage, ev, sizeof(CRGBColor), &fColor);
  895.         
  896.     ENDTRY
  897. }
  898.  
  899.  
  900. //------------------------------------------------------------------------------
  901. // CShape::Write
  902. // We assume that the storage unit is focused to a property and value and
  903. // that the current offset is a good place to write out a shape.
  904. //------------------------------------------------------------------------------
  905. void CShape::Write(Environment* ev, ODStorageUnitView* view, CCloneInfo* cloneInfo)
  906. {
  907.     UNUSED(cloneInfo);
  908.  
  909.     TRY
  910.         // Write the rectangle
  911.         StorageUnitViewSetValue(view, ev, sizeof(Rect), &fRect);
  912.         
  913.         // Write the shape type
  914.         StorageUnitViewSetValue(view, ev, sizeof(ODSShort), &fShapeType);
  915.         
  916.         // Write the number of handles
  917.         StorageUnitViewSetValue(view, ev, sizeof(ODSShort), &fNumberOfHandles);
  918.     
  919.         // Write the shape color
  920.         StorageUnitViewSetValue(view, ev, sizeof(CRGBColor), &fColor);
  921.     
  922.     ENDTRY
  923. }
  924.  
  925.  
  926. //------------------------------------------------------------------------------
  927. // CShape::Write
  928. // We assume that the storage unit is focused to a property and value and
  929. // that the current offset is a good place to write out a shape.
  930. //------------------------------------------------------------------------------
  931. void CShape::Write(Environment* ev, ODStorageUnit* storage, CCloneInfo* cloneInfo)
  932. {
  933.     UNUSED(cloneInfo);
  934.  
  935.     TRY
  936.         // Write the rectangle
  937.         StorageUnitSetValue(storage, ev, sizeof(Rect), &fRect);
  938.         
  939.         // Write the shape type
  940.         StorageUnitSetValue(storage, ev, sizeof(ODSShort), &fShapeType);
  941.         
  942.         // Write the number of handles
  943.         StorageUnitSetValue(storage, ev, sizeof(ODSShort), &fNumberOfHandles);
  944.     
  945.         // Write the shape color
  946.         StorageUnitSetValue(storage, ev, sizeof(CRGBColor), &fColor);
  947.     
  948.     ENDTRY
  949. }
  950.  
  951. void CShape::Publish(Environment* ev, CPublishLink *publishLink)
  952. {
  953.     // If its subscribed, nobody should be publishing it.
  954.     ASSERT(!fSubscribeLink, kODErrAssertionFailed);
  955.     
  956.     fPublishLinks->AddLast(publishLink);
  957. }
  958.  
  959.  
  960. ODBoolean    CShape::IsPublished()
  961. {
  962.     return (fPublishLinks->Count() != 0);
  963. }
  964.  
  965.  
  966. #pragma segment Main
  967. void CShape::Subscribe(Environment* ev, CSubscribeLink* link)
  968. {
  969.     ASSERT(fSubscribeLink == kODNULL, kODErrAssertionFailed);
  970.     
  971.     fPublishLinks->RemoveAllLinks();
  972.     
  973.     fSubscribeLink= link;
  974. }
  975.  
  976. #pragma segment Main
  977. void CShape::SetExternalizationIndex(ODUShort index)
  978. {
  979.     fExternalizationIndex = index;
  980. }
  981.  
  982.  
  983. #pragma segment Main
  984. ODUShort CShape::GetExternalizationIndex()
  985. {
  986.     return fExternalizationIndex;
  987. }
  988.  
  989.  
  990. #pragma segment Main
  991. void CShape::Unpublish(Environment* ev, CPublishLink* publishLink)
  992. {
  993.     // $$$$$ Test could probably be replaced by an assertion.
  994.     if (!fSubscribeLink)
  995.         fPublishLinks->Remove(publishLink);
  996. }
  997.  
  998.  
  999. #pragma segment Main
  1000. void CShape::Unsubscribe(Environment* ev)
  1001. {
  1002.     ASSERT(fSubscribeLink, kODErrAssertionFailed);
  1003.     ASSERT(fPublishLinks->Count() == 0, kODErrAssertionFailed);
  1004.         
  1005.     COrdListIterator iter(fSubscribeLink->GetPublishLinks());
  1006.     for (CPublishLink* pLink = (CPublishLink*)iter.First(); iter.IsNotComplete(); pLink = (CPublishLink*)iter.Next())
  1007.     {
  1008.         fPublishLinks->AddLast(pLink);
  1009.     }
  1010.     
  1011.     fSubscribeLink = kODNULL;    
  1012. }
  1013.  
  1014.  
  1015.  
  1016. //=============================================================================
  1017. // class CRectangleShape
  1018. //=============================================================================
  1019.  
  1020. //------------------------------------------------------------------------------
  1021. // Method:        CRectangleShape Constructor
  1022. //
  1023. // Description:    We allow the caller to pass in a shape type here so that 
  1024. // classes can derive from this one and have their own type.
  1025. //
  1026. //------------------------------------------------------------------------------
  1027. CRectangleShape::CRectangleShape(ODSShort shapeType) : 
  1028.     CShape(kNumberOfHandles, shapeType)
  1029. {
  1030. }
  1031.  
  1032. //------------------------------------------------------------------------------
  1033. // CRectangleShape::~CRectangleShape
  1034. //------------------------------------------------------------------------------
  1035. CRectangleShape::~CRectangleShape()
  1036. {
  1037. }
  1038.  
  1039.  
  1040.  
  1041. //------------------------------------------------------------------------------
  1042. // CRectangleShape::CreateDragShape
  1043. // Be sure to release the shape returned from this call
  1044. //------------------------------------------------------------------------------
  1045. ODShape* CRectangleShape::CreateDragShape(Environment *ev, ODFacet* facet)
  1046. {
  1047.     ODRect bounds(fRect);
  1048.         
  1049.     ODShape* dragRgn = facet->CreateShape(ev);
  1050.     dragRgn->SetRectangle(ev, &bounds);
  1051.     
  1052.     bounds.Inset(ff(1), ff(1));
  1053.     
  1054.     ODShape* donutHole = facet->CreateShape(ev);
  1055.     
  1056.     donutHole->SetRectangle(ev, &bounds);
  1057.     dragRgn->Subtract(ev, donutHole);
  1058.     ODReleaseObject(ev, donutHole);
  1059.     
  1060.     return dragRgn;
  1061. }
  1062.  
  1063.  
  1064. //------------------------------------------------------------------------------
  1065. // CRectangleShape::OutlineShape
  1066. //------------------------------------------------------------------------------
  1067. void CRectangleShape::OutlineShape(ODFacet* facet, const Rect& rect, ODBoolean draw)
  1068. {
  1069.     ::FrameRect(&rect);            
  1070. }
  1071.  
  1072. //------------------------------------------------------------------------------
  1073. // CRectangleShape::HitTest
  1074. //------------------------------------------------------------------------------
  1075. ODBoolean CRectangleShape::HitTest(Environment *ev, const Point& where) const
  1076. {
  1077.     ODRect bounds(fRect);
  1078.     ODPoint mouse(where);
  1079.  
  1080.     return bounds.Contains(mouse);
  1081. }
  1082.  
  1083.  
  1084.  
  1085. //------------------------------------------------------------------------------
  1086. // CRectangleShape::DrawShape
  1087. //------------------------------------------------------------------------------
  1088. void CRectangleShape::DrawShape(Environment* ev, ODFacet* facet)
  1089. {
  1090.     CShape::DrawShape(ev, facet);
  1091.     
  1092.     if (this->IsShown())
  1093.     {
  1094.         // Save the Pen
  1095.         PenState tPen;
  1096.         RGBColor tColor;
  1097.         GetPenState(&tPen);
  1098.         GetForeColor(&tColor);
  1099.         
  1100.         // Draw the color
  1101.         if (this->GetCanDrawColor())
  1102.         {
  1103.             ::RGBForeColor((RGBColor*)GetColor());
  1104.             
  1105.             //  Paint the rectangle
  1106.             ::PaintRect(&fRect);
  1107.         }
  1108.         
  1109.         // Frame the rectangle
  1110.         RGBForeColor((RGBColor*)&gGlobals->fBlackColor);
  1111.         ::FrameRect(&fRect);
  1112.     
  1113.         // Restore state
  1114.         RGBForeColor(&tColor);
  1115.         SetPenState(&tPen);
  1116.     }
  1117.  
  1118. }
  1119.  
  1120. //=============================================================================
  1121. // class COvalShape
  1122. //=============================================================================
  1123.  
  1124. //------------------------------------------------------------------------------
  1125. // Method:        COvalShape Constructor
  1126. //
  1127. //
  1128. //------------------------------------------------------------------------------
  1129. COvalShape::COvalShape() : CShape(kNumberOfHandles, kOvalShape)
  1130. {
  1131. }
  1132.  
  1133. //------------------------------------------------------------------------------
  1134. // COvalShape::~COvalShape
  1135. //------------------------------------------------------------------------------
  1136. COvalShape::~COvalShape()
  1137. {
  1138. }
  1139.  
  1140. //------------------------------------------------------------------------------
  1141. // COvalShape::GetBoundingRegion
  1142. // Be sure to dispose of the region returned from this call
  1143. //------------------------------------------------------------------------------
  1144. ODRgnHandle COvalShape::GetBoundingRegion() const
  1145. {
  1146.     ODRgnHandle ovalRgn = ::NewRgn();
  1147.     THROW_IF_NULL(ovalRgn);
  1148.     
  1149.     // Save the Pen
  1150.     PenState tPen;
  1151.     RGBColor tColor;
  1152.     GetPenState(&tPen);
  1153.     GetForeColor(&tColor);
  1154.     
  1155.     // Frame the oval
  1156.     PenNormal();
  1157.     
  1158.     //  Generate a QD region for the oval
  1159.     ::OpenRgn();
  1160.     
  1161.     ::FrameOval(&fRect);
  1162.     ::CloseRgn(ovalRgn);
  1163.     
  1164.     // Restore state
  1165.     RGBForeColor(&tColor);
  1166.     SetPenState(&tPen);
  1167.     
  1168.     return ovalRgn;
  1169. }
  1170.  
  1171. //------------------------------------------------------------------------------
  1172. // COvalShape::CreateDragShape
  1173. // Be sure to release the shape returned from this call
  1174. //------------------------------------------------------------------------------
  1175. ODShape* COvalShape::CreateDragShape(Environment *ev, ODFacet* facet)
  1176. {
  1177.     ODRgnHandle ovalRgn = this->GetBoundingRegion();    
  1178.     
  1179.     ODShape* dragRgn = facet->CreateShape(ev);
  1180.     dragRgn->SetQDRegion(ev, ovalRgn);
  1181.         
  1182.     return dragRgn;
  1183. }
  1184.  
  1185. //------------------------------------------------------------------------------
  1186. // COvalShape::OutlineShape
  1187. //------------------------------------------------------------------------------
  1188. void COvalShape::OutlineShape(ODFacet* facet, const Rect& rect, ODBoolean draw)
  1189. {
  1190.     // Should draw the actual shape instead of just an outline
  1191.     ::FrameOval(&rect);            
  1192. }
  1193.  
  1194. //------------------------------------------------------------------------------
  1195. // COvalShape::HitTest
  1196. //------------------------------------------------------------------------------
  1197. ODBoolean COvalShape::HitTest(Environment *ev, const Point& where) const
  1198. {
  1199.     ODBoolean result = kODFalse;
  1200.     
  1201.     //  Generate a QD region for the oval
  1202.     RgnHandle ovalRgn = NewRgn();
  1203.     THROW_IF_NULL(ovalRgn);
  1204.     
  1205.     // Save the Pen
  1206.     PenState tPen;
  1207.     RGBColor tColor;
  1208.     GetPenState(&tPen);
  1209.     GetForeColor(&tColor);
  1210.     
  1211.     OpenRgn();
  1212.     PenNormal();
  1213.     FrameOval(&fRect);
  1214.     CloseRgn(ovalRgn);
  1215.     
  1216.     // Restore state
  1217.     RGBForeColor(&tColor);
  1218.     SetPenState(&tPen);
  1219.         
  1220.     // Test the point against the region
  1221.     result = PtInRgn(where, ovalRgn);
  1222.  
  1223.     // Free the region
  1224.     DisposeRgn(ovalRgn);
  1225.  
  1226.     return result;
  1227. }
  1228.  
  1229.  
  1230.  
  1231. //------------------------------------------------------------------------------
  1232. // COvalShape::DrawShape
  1233. //------------------------------------------------------------------------------
  1234. void COvalShape::DrawShape(Environment* ev, ODFacet* facet)
  1235. {
  1236.     CShape::DrawShape(ev, facet);    
  1237.     
  1238.     if (this->IsShown())
  1239.     {
  1240.         // Save the Pen
  1241.         PenState tPen;
  1242.         RGBColor tColor;
  1243.         GetPenState(&tPen);
  1244.         GetForeColor(&tColor);
  1245.         
  1246.         RGBForeColor((RGBColor*)GetColor());
  1247.         
  1248.         //  Paint the rectangle
  1249.         ::PaintOval(&fRect);
  1250.         
  1251.         // Frame the rectangle
  1252.         RGBForeColor((RGBColor*)&gGlobals->fBlackColor);
  1253.         ::FrameOval(&fRect);
  1254.     
  1255.         // Restore state
  1256.         RGBForeColor(&tColor);
  1257.         SetPenState(&tPen);
  1258.     }
  1259. }
  1260.  
  1261.  
  1262. //=============================================================================
  1263. // class CPolygonShape
  1264. //=============================================================================
  1265.  
  1266. //------------------------------------------------------------------------------
  1267. // Method:        CPolygonShape Constructor
  1268. //
  1269. //
  1270. //------------------------------------------------------------------------------
  1271. CPolygonShape::CPolygonShape() : CShape(kNumberOfHandles, kPolygonShape)
  1272. {
  1273.     fPolygon = kODNULL;
  1274.     fSides = 0;
  1275. }
  1276.  
  1277. //------------------------------------------------------------------------------
  1278. // CPolygonShape::~CPolygonShape
  1279. //------------------------------------------------------------------------------
  1280. CPolygonShape::~CPolygonShape()
  1281. {
  1282.     KillPoly(fPolygon);
  1283. }
  1284.  
  1285. //------------------------------------------------------------------------------
  1286. // CShape::Read
  1287. // We assume that the storage unit is focused to a property and value and
  1288. // that the current offset is the beginning of a shape.
  1289. //------------------------------------------------------------------------------
  1290. void CPolygonShape::Read(Environment* ev, ODStorageUnit* storage, CCloneInfo* cloneInfo)
  1291. {
  1292.     CShape::Read(ev, storage, cloneInfo);
  1293.     
  1294.     this->SetPolygon(3);
  1295. }
  1296.  
  1297. //------------------------------------------------------------------------------
  1298. // CPolygonShape::SetPolygon
  1299. // Assumes fRect is set by this time.
  1300. //------------------------------------------------------------------------------
  1301. void CPolygonShape::SetPolygon(ODSShort numSides)
  1302. {
  1303.     fSides = numSides;
  1304.  
  1305.     // Initialize the polygon
  1306.     fPolygon = OpenPoly();
  1307.     
  1308.     ODSShort shapeWidth = fRect.right-fRect.left;
  1309.     
  1310.     // Test with triangle
  1311.     MoveTo(fRect.left + shapeWidth / 2,fRect.top);
  1312.     LineTo(fRect.right, fRect.bottom);
  1313.     LineTo(fRect.left, fRect.bottom);
  1314.     LineTo(fRect.left + shapeWidth / 2,fRect.top);
  1315.     
  1316.     // Terminate recording of the polygon
  1317.     ClosePoly();
  1318. }
  1319.  
  1320. //------------------------------------------------------------------------------
  1321. // CPolygonShape::GetBoundingRegion
  1322. // Be sure to dispose of the region returned from this call
  1323. //------------------------------------------------------------------------------
  1324. ODRgnHandle CPolygonShape::GetBoundingRegion() const
  1325. {
  1326.     ODRgnHandle PolygonRgn = ::NewRgn();
  1327.     THROW_IF_NULL(PolygonRgn);
  1328.     
  1329.     // Save the Pen
  1330.     PenState tPen;
  1331.     RGBColor tColor;
  1332.     GetPenState(&tPen);
  1333.     GetForeColor(&tColor);
  1334.     
  1335.     //  Generate a QD region for the Polygon
  1336.     ::OpenRgn();
  1337.     ::PenNormal();
  1338.     ::FramePoly(fPolygon);
  1339.     ::CloseRgn(PolygonRgn);
  1340.     
  1341.     // Restore state
  1342.     RGBForeColor(&tColor);
  1343.     SetPenState(&tPen);
  1344.     
  1345.     return PolygonRgn;
  1346. }
  1347.  
  1348. //------------------------------------------------------------------------------
  1349. // CPolygonShape::Resize
  1350. //------------------------------------------------------------------------------
  1351. void CPolygonShape::Resize(Environment *ev, Rect& baseRect, Rect& resizeRect)
  1352. {
  1353.     CShape::Resize(ev, baseRect, resizeRect);
  1354.     
  1355.     this->SetPolygon(3);
  1356. }
  1357.  
  1358. //------------------------------------------------------------------------------
  1359. // CPolygonShape::CreateDragShape
  1360. // Be sure to release the shape returned from this call
  1361. //------------------------------------------------------------------------------
  1362. ODShape* CPolygonShape::CreateDragShape(Environment *ev, ODFacet* facet)
  1363. {
  1364.     ODRgnHandle PolygonRgn = this->GetBoundingRegion();    
  1365.     
  1366.     ODShape* dragRgn = facet->CreateShape(ev);
  1367.     dragRgn->SetQDRegion(ev, PolygonRgn);
  1368.         
  1369.     return dragRgn;
  1370. }
  1371.  
  1372. //------------------------------------------------------------------------------
  1373. // CPolygonShape::OffsetShape
  1374. //------------------------------------------------------------------------------
  1375.  
  1376. void CPolygonShape::OffsetShape(Environment* ev, ODCoordinate xDelta, ODCoordinate yDelta)
  1377. {
  1378.     // Call inherited
  1379.     CShape::OffsetShape(ev, xDelta, yDelta);
  1380.  
  1381.     ::OffsetPoly(fPolygon, FixedToInt(xDelta), FixedToInt(yDelta));
  1382. }
  1383.  
  1384.  
  1385. //------------------------------------------------------------------------------
  1386. // CPolygonShape::OutlineShape
  1387. //------------------------------------------------------------------------------
  1388. void CPolygonShape::OutlineShape(ODFacet* facet, const Rect& rect, ODBoolean draw)
  1389. {
  1390.     // Should draw the actual shape instead of just an outline
  1391.     ::FramePoly(fPolygon);            
  1392. }
  1393.  
  1394. //------------------------------------------------------------------------------
  1395. // CPolygonShape::HitTest
  1396. //------------------------------------------------------------------------------
  1397. ODBoolean CPolygonShape::HitTest(Environment *ev, const Point& where) const
  1398. {
  1399.     ODBoolean result = kODFalse;
  1400.     
  1401.     //  Generate a QD region for the Polygon
  1402.     RgnHandle PolygonRgn = NewRgn();
  1403.     THROW_IF_NULL(PolygonRgn);
  1404.     
  1405.     // Save the Pen
  1406.     PenState tPen;
  1407.     RGBColor tColor;
  1408.     GetPenState(&tPen);
  1409.     GetForeColor(&tColor);
  1410.     
  1411.     ::OpenRgn();
  1412.     ::PenNormal();
  1413.     ::FramePoly(fPolygon);
  1414.     ::CloseRgn(PolygonRgn);
  1415.         
  1416.     // Restore state
  1417.     RGBForeColor(&tColor);
  1418.     SetPenState(&tPen);
  1419.     
  1420.     // Test the point against the region
  1421.     result = PtInRgn(where, PolygonRgn);
  1422.  
  1423.     // Free the region
  1424.     DisposeRgn(PolygonRgn);
  1425.  
  1426.     return result;
  1427. }
  1428.  
  1429.  
  1430.  
  1431. //------------------------------------------------------------------------------
  1432. // CPolygonShape::DrawShape
  1433. //------------------------------------------------------------------------------
  1434. void CPolygonShape::DrawShape(Environment* ev, ODFacet* facet)
  1435. {
  1436.     CShape::DrawShape(ev, facet);    
  1437.     
  1438.     if (this->IsShown())
  1439.     {
  1440.         // Save the Pen
  1441.         PenState tPen;
  1442.         RGBColor tColor;
  1443.         GetPenState(&tPen);
  1444.         GetForeColor(&tColor);
  1445.     
  1446.         RGBForeColor((RGBColor*)GetColor());
  1447.         
  1448.         //  Paint the rectangle
  1449.         ::PaintPoly(fPolygon);
  1450.         
  1451.         // Frame the rectangle
  1452.         RGBForeColor((RGBColor*)&gGlobals->fBlackColor);
  1453.         ::FramePoly(fPolygon);
  1454.     
  1455.         // Restore state
  1456.         RGBForeColor(&tColor);
  1457.         SetPenState(&tPen);
  1458.     }
  1459. }
  1460.  
  1461.  
  1462. //=============================================================================
  1463. // class CEmbeddingShape
  1464. //=============================================================================
  1465.  
  1466. //------------------------------------------------------------------------------
  1467. // CEmbeddingShape::CEmbeddingShape
  1468. //------------------------------------------------------------------------------
  1469. CEmbeddingShape::CEmbeddingShape(DrawEditor* drawEditor) : 
  1470.     CRectangleShape(kEmbeddingShape)
  1471. {
  1472.     fDrawEditor = drawEditor;
  1473.     fFrozen = kODFalse;
  1474.     fFrameProxies = kODNULL;
  1475.     
  1476.     this->SetCanDrawColor(kODFalse);
  1477.  
  1478.     // Go ahead and allocate the list here
  1479.     fFrameProxies = new COrderedList;
  1480.  
  1481. }
  1482.  
  1483.  
  1484. //------------------------------------------------------------------------------
  1485. // CEmbeddingShape::~CEmbeddingShape
  1486. //------------------------------------------------------------------------------
  1487. CEmbeddingShape::~CEmbeddingShape()
  1488. {
  1489.     Environment* ev = somGetGlobalEnvironment();
  1490.     
  1491.     if (fFrameProxies)
  1492.     {
  1493.         COrdListIterator iter(fFrameProxies);
  1494.         for ( CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  1495.                 iter.IsNotComplete(); frameProxy = (CEmbeddedFrameProxy*)iter.Next())
  1496.         {
  1497.             // This code assumes that the shape has been removed before now.
  1498.             delete frameProxy;
  1499.         }
  1500.         
  1501.         delete fFrameProxies;
  1502.         fFrameProxies = kODNULL;
  1503.     }
  1504.  
  1505. }
  1506.  
  1507.  
  1508. //------------------------------------------------------------------------------
  1509. // CEmbeddingShape::SetBoundingBox
  1510. //------------------------------------------------------------------------------
  1511.  
  1512. void CEmbeddingShape::SetBoundingBox(Environment* ev, const Rect& bounds)
  1513. {
  1514.     CShape::SetBoundingBox(ev, bounds);
  1515.     
  1516.     // Update frame shapes for frames we are for which we are proxying
  1517.     this->SetProxyBounds(ev, fRect);
  1518. }
  1519.  
  1520.  
  1521. //------------------------------------------------------------------------------
  1522. // CEmbeddingShape::SetBoundingBox
  1523. //------------------------------------------------------------------------------
  1524.  
  1525. void CEmbeddingShape::SetBoundingBox(Environment* ev, ODShape* bounds)
  1526. {
  1527.     CShape::SetBoundingBox(ev, bounds);
  1528.     
  1529.     // Update frame shapes for frames we are for which we are proxying
  1530.     this->SetProxyBounds(ev, fRect);
  1531. }
  1532.  
  1533.  
  1534. //------------------------------------------------------------------------------
  1535. // CEmbeddingShape::SetShapeRectangle
  1536. //
  1537. // Set the rectangle for the shape without adjusting the embedded frames bounds.
  1538. // This is necessary in cases where OpenDoc is gonig to change the embedded frame
  1539. // shape on us and we need to adjust the intrinsic shape's bounds without changing
  1540. // the frame shape ( causing stack overflow ). 
  1541. //------------------------------------------------------------------------------
  1542.  
  1543. void CEmbeddingShape::SetShapeRectangle(Environment* ev, ODShape* bounds)
  1544. {
  1545.     // Change the bounds rect of the shape without affecting the embedded frame(s)
  1546.     ODRgnHandle tRegion = bounds->GetQDRegion(ev);
  1547.     Rect tRect = (*tRegion)->rgnBBox;
  1548.     
  1549.     fRect = tRect;
  1550. }
  1551.  
  1552.  
  1553. //------------------------------------------------------------------------------
  1554. // CEmbeddingShape::SetBoundingBox
  1555. //------------------------------------------------------------------------------
  1556.  
  1557. void CEmbeddingShape::SetBoundingBox(Environment* ev, const Point& anchorPoint,  const Point& currentPoint)
  1558. {
  1559.     CShape::SetBoundingBox(ev, anchorPoint, currentPoint);
  1560.     
  1561.     // Update frame shapes for frames we are for which we are proxying
  1562.     this->SetProxyBounds(ev, fRect);
  1563. }
  1564.  
  1565.  
  1566. //------------------------------------------------------------------------------
  1567. // CEmbeddingShape::SetProxyBounds
  1568. //------------------------------------------------------------------------------
  1569.  
  1570. void CEmbeddingShape::SetProxyBounds(Environment* ev, const Rect& bounds)
  1571. {
  1572.     ODRect tRect(bounds);
  1573.     
  1574.     COrdListIterator iter(fFrameProxies);
  1575.     for ( CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  1576.             iter.IsNotComplete(); frameProxy = (CEmbeddedFrameProxy*)iter.Next())
  1577.     {
  1578.         frameProxy->ResizeFrame(ev, tRect);
  1579.     }
  1580. }
  1581.  
  1582.  
  1583. //------------------------------------------------------------------------------
  1584. // Method:        AddFrameProxy
  1585. //
  1586. // Description:    
  1587. //
  1588. //------------------------------------------------------------------------------
  1589. void CEmbeddingShape::AddFrameProxy(CEmbeddedFrameProxy* frameProxy)
  1590. {
  1591.     fFrameProxies->AddLast(frameProxy);
  1592. }
  1593.  
  1594. //------------------------------------------------------------------------------
  1595. // CEmbeddingShape::MoveAfter
  1596. // This method is called to move 'this' shape after the given one.
  1597. //------------------------------------------------------------------------------
  1598.  
  1599. void CEmbeddingShape::MoveAfter(Environment* ev, CShape* shape)
  1600. {
  1601.     // If the given shape is not an embedding shape then
  1602.     // we have nothing to do
  1603.     if (shape->GetShapeType() != kEmbeddingShape)
  1604.     {
  1605.         return;
  1606.     }
  1607.     
  1608.     COrdListIterator iter(fFrameProxies);
  1609.     for ( CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  1610.             iter.IsNotComplete(); frameProxy = (CEmbeddedFrameProxy*)iter.Next())
  1611.     {
  1612.         // Get the embedded frame for this shape
  1613.         ODFrame* embeddedFrame = frameProxy->GetFrame(ev);
  1614.         
  1615.         // Iterate over the facets for this frame
  1616.         ODFrameFacetIterator* facetIter = embeddedFrame->CreateFacetIterator(ev);
  1617.         for (ODFacet* embeddedFacet = facetIter->First(ev); 
  1618.             facetIter->IsNotComplete(ev); embeddedFacet = facetIter->Next(ev))
  1619.         {
  1620.             // Get the facet for the given shape which shares our
  1621.             // containing facet
  1622.             ODFacet* containingFacet = embeddedFacet->GetContainingFacet(ev);
  1623.             ODFacet* shapeFacet = ((CEmbeddingShape*)shape)->GetEmbeddedFacet(ev, containingFacet);
  1624.             containingFacet->MoveBehind(ev, embeddedFacet, shapeFacet);
  1625.         }
  1626.     
  1627.         delete facetIter;
  1628.     }
  1629.     
  1630.     // Invalidate the shapes
  1631.     fDrawEditor->InvalidateShape(ev, this);
  1632.     fDrawEditor->InvalidateShape(ev, shape);
  1633. }
  1634.  
  1635. //------------------------------------------------------------------------------
  1636. // CEmbeddingShape::MoveBefore
  1637. // This method is called to move 'this' shape before the given one.
  1638. //------------------------------------------------------------------------------
  1639.  
  1640. void CEmbeddingShape::MoveBefore(Environment* ev, CShape* shape)
  1641. {
  1642.     // If the given shape is not an embedding shape then
  1643.     // we have nothing to do
  1644.     if (shape->GetShapeType() != kEmbeddingShape)
  1645.     {
  1646.         return;
  1647.     }
  1648.     
  1649.     COrdListIterator iter(fFrameProxies);
  1650.     for ( CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  1651.             iter.IsNotComplete(); frameProxy = (CEmbeddedFrameProxy*)iter.Next())
  1652.     {
  1653.         // Get the embedded frame for this shape
  1654.         ODFrame* embeddedFrame = frameProxy->GetFrame(ev);
  1655.         
  1656.         // Iterate over the facets for this frame
  1657.         ODFrameFacetIterator* facetIter = embeddedFrame->CreateFacetIterator(ev);
  1658.         for (ODFacet* embeddedFacet = facetIter->First(ev); 
  1659.             facetIter->IsNotComplete(ev); embeddedFacet = facetIter->Next(ev))
  1660.         {
  1661.             // Get the facet for the given shape which shares our
  1662.             // containing facet
  1663.             ODFacet* containingFacet = embeddedFacet->GetContainingFacet(ev);
  1664.             ODFacet* shapeFacet = ((CEmbeddingShape*)shape)->GetEmbeddedFacet(ev, containingFacet);
  1665.             containingFacet->MoveBefore(ev, embeddedFacet, shapeFacet);
  1666.         }
  1667.     
  1668.         delete facetIter;
  1669.     }
  1670.     
  1671.     // Invalidate the shapes
  1672.     fDrawEditor->InvalidateShape(ev, this);
  1673.     fDrawEditor->InvalidateShape(ev, shape);
  1674. }
  1675.  
  1676. //------------------------------------------------------------------------------
  1677. // CEmbeddingShape::SelectShape
  1678. //
  1679. // Description:    
  1680. //
  1681. //------------------------------------------------------------------------------
  1682.  
  1683. void CEmbeddingShape::SelectShape(Environment* ev, ODBoolean state)
  1684. {
  1685.     CRectangleShape::SelectShape(ev, state);
  1686.  
  1687.     // Set the selected & hilighted flags of all facets of all our frame
  1688.     // proxies
  1689.     COrdListIterator iter(fFrameProxies);
  1690.     for ( CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  1691.             iter.IsNotComplete(); frameProxy = (CEmbeddedFrameProxy*)iter.Next())
  1692.     {
  1693.         TRY
  1694.             ODFrame* frame = frameProxy->GetFrame(ev);
  1695.             THROW_IF_NULL(frame);
  1696.                     
  1697.             ODFrameFacetIterator* iter2 = frame->CreateFacetIterator(ev);
  1698.             for (ODFacet* facet = iter2->First(ev); iter2->IsNotComplete(ev); facet = iter2->Next(ev))
  1699.             {    
  1700.                 TempODWindow window = facet->GetFrame(ev)->AcquireWindow(ev);
  1701.                 THROW_IF_NULL(window);
  1702.                 
  1703.                 ODBoolean active = window->IsActive(ev);
  1704.                 
  1705.                 ODHighlight highlight;
  1706.                 
  1707.                 if ( this->IsSelected() && active ) 
  1708.                     highlight = kODFullHighlight;
  1709.                 else if ( this->IsSelected() && !active ) 
  1710.                     highlight = kODDimHighlight;
  1711.                 else 
  1712.                     highlight = kODNoHighlight;
  1713.                 
  1714.                 facet->SetSelected(ev, state);
  1715.                 
  1716.                 ::ChangeFacetHighlight(ev, facet, highlight);
  1717.             }
  1718.             
  1719.             delete iter2;
  1720.         
  1721.         CATCH_ALL
  1722.             DebugStr("\pProblem selecting shape!");
  1723.         ENDTRY
  1724.     }
  1725.             
  1726. }
  1727.  
  1728.  
  1729. //------------------------------------------------------------------------------
  1730. // CEmbeddingShape::DrawShape
  1731. //------------------------------------------------------------------------------
  1732. void CEmbeddingShape::DrawShape(Environment* ev, ODFacet* facet)
  1733. {    
  1734.     if (this->IsShown())
  1735.     {
  1736.         // Draw the embedded part
  1737.         RgnHandle tRegion = NewRgn();
  1738.         THROW_IF_NULL(tRegion);
  1739.         
  1740.         // Temp Shape
  1741.         ODShape* tShape = facet->CreateShape(ev);
  1742.         
  1743.         // Get the clipping region & convert to ODShape
  1744.         ODShape* tClippingShape = facet->CreateShape(ev);
  1745.         GetClip(tRegion);
  1746.         tClippingShape->SetQDRegion(ev, tRegion);    // SetQDRegion consumes the region
  1747.         
  1748.         COrdListIterator iter(fFrameProxies);
  1749.         for ( CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  1750.                 iter.IsNotComplete(); frameProxy = (CEmbeddedFrameProxy*)iter.Next())
  1751.         {
  1752.             // Getting the frame will also ensure that there is one ( a frame, that is )
  1753.             ODFrame* embeddedFrame = frameProxy->GetFrame(ev);
  1754.             
  1755.             ODFrameFacetIterator* iter = embeddedFrame->CreateFacetIterator(ev);
  1756.             for (ODFacet* embeddedFacet = iter->First(ev); iter->IsNotComplete(ev); embeddedFacet = iter->Next(ev))
  1757.             {
  1758.                 // Set up the clip for the embedded facet
  1759.                 // DCS $$$$$ ? Need this ??
  1760.                 CFocus embeddedDraw(ev, embeddedFacet);
  1761.                 
  1762.                 // Get the current clip shape
  1763.                 tShape->CopyFrom(ev, tClippingShape);
  1764.                 
  1765.                 // Remove the drawn area from our clip shape
  1766.                 tClippingShape->Subtract(ev, tShape);
  1767.                 
  1768.                 // Transform the shape before calling the embedded facet to draw
  1769.                 Point offset;
  1770.                 Rect tRect;
  1771.                 
  1772.                 this->GetBoundingBox(&tRect);
  1773.                 offset.h = tRect.left;
  1774.                 offset.v = tRect.top;
  1775.                 
  1776.                 // Convert shape's transform from parent frame to embedded frame
  1777.                 ODTransform* tTransform = embeddedFacet->AcquireExternalTransform(ev, kODNULL);
  1778.                 tShape->InverseTransform(ev, tTransform);    
  1779.                 ODReleaseObject(ev, tTransform);
  1780.                         
  1781.                 // Get the embedded facet's clip shape so we can subtract it from our working clip
  1782.                 ODShape* tEmbeddedClipShape = embeddedFacet->AcquireClipShape(ev, kODNULL);
  1783.                 tShape->CopyFrom(ev, tEmbeddedClipShape);
  1784.                 ODReleaseObject(ev, tEmbeddedClipShape);
  1785.                 
  1786.                 // Give the shape the right transform
  1787.                 tTransform = embeddedFacet->AcquireExternalTransform(ev, kODNULL);
  1788.                 tShape->Transform(ev, tTransform);
  1789.                 ODReleaseObject(ev, tTransform);
  1790.             }
  1791.         }
  1792.         
  1793.         // Release acquired geometry
  1794.         ODReleaseObject(ev, tShape);
  1795.         ODReleaseObject(ev, tClippingShape);
  1796.     
  1797.         // We don't want the rectangle to draw, so call CShape::Draw instead.
  1798.             CShape::DrawShape(ev, facet);
  1799.     }
  1800. }
  1801.  
  1802.  
  1803. //----------------------------------------------------------------------------------------
  1804. // CEmbeddingShape::Embed
  1805. //
  1806. // Description:    Embed the given part with the ( optional ) given frame. If no embedded 
  1807. // frame is passed in, this method will create one.
  1808. //
  1809. //----------------------------------------------------------------------------------------
  1810.  
  1811. void CEmbeddingShape::Embed(    Environment* ev, 
  1812.                                 ODPart* part, 
  1813.                                 ODFrame* containingFrame, 
  1814.                                 ODID embeddedFrameID)
  1815. {
  1816.  
  1817.     ODDraft*    draft = fDrawEditor->GetDraft(ev);
  1818.         
  1819.     // Frames are represented by proxies
  1820.     CEmbeddedFrameProxy* frameProxy = kODNULL;
  1821.     
  1822.     if (embeddedFrameID == kODNULL)
  1823.     {
  1824.         // Make a proxy
  1825.         frameProxy = new CEmbeddedFrameProxy();
  1826.         frameProxy->InitializeEmbeddedFrameProxy(ev, 
  1827.                                     fDrawEditor, 
  1828.                                     this, 
  1829.                                     containingFrame, 
  1830.                                     part);
  1831.     }
  1832.     else
  1833.     {
  1834.         // Make a proxy for it, using the frame passed in
  1835.         frameProxy = new CEmbeddedFrameProxy();
  1836.         frameProxy->InitializeEmbeddedFrameProxy(ev, 
  1837.                                         fDrawEditor, 
  1838.                                         this, 
  1839.                                         embeddedFrameID, 
  1840.                                         containingFrame);    
  1841.     
  1842.         // Get the shape of the frame and set the size of the CEmbeddingShape
  1843.         // we should delay this until later. Causing frame to be loaded to early.
  1844.         // DCS $$$$$
  1845.         ODFrame* tFrame = frameProxy->GetFrame(ev);
  1846.                 
  1847.         ODShape* tShape = tFrame->AcquireFrameShape(ev, kODNULL);
  1848.         ODRgnHandle tODRegion = tShape->GetQDRegion(ev);
  1849.         this->SetBoundingBox(ev, (*tODRegion)->rgnBBox);
  1850.         
  1851.         // Release acquired geometry
  1852.         ODReleaseObject(ev, tShape);
  1853.     }                                                
  1854.  
  1855.     // Add to our list of frameProxies
  1856.     this->AddFrameProxy(frameProxy);
  1857. }
  1858.  
  1859. //----------------------------------------------------------------------------------------
  1860. // CEmbeddingShape::SetFrozen
  1861. //----------------------------------------------------------------------------------------
  1862.  
  1863. ODBoolean CEmbeddingShape::SetFrozen(ODBoolean state)
  1864. {
  1865.     return kODFalse;
  1866. }
  1867.  
  1868.  
  1869. //----------------------------------------------------------------------------------------
  1870. // CEmbeddingShape::Show
  1871. //----------------------------------------------------------------------------------------
  1872.  
  1873. void CEmbeddingShape::Show(Environment* ev, ODBoolean show)
  1874. {
  1875.     if (show)
  1876.     {
  1877.         if (!this->IsShown())
  1878.         {
  1879.             // Iterate over all the proxies and attach, if necessary
  1880.             COrdListIterator iter(fFrameProxies);
  1881.             for ( CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  1882.                     iter.IsNotComplete(); frameProxy = (CEmbeddedFrameProxy*)iter.Next())
  1883.             {
  1884.                 if (!frameProxy->IsAttached(ev))
  1885.                     frameProxy->Attach(ev);    
  1886.             }
  1887.         }
  1888.     }
  1889.     else
  1890.     // We are hiding
  1891.     {
  1892.         if (this->IsShown())
  1893.         {
  1894.             // Iterate over all the proxies and detach, if necessary
  1895.             COrdListIterator iter(fFrameProxies);
  1896.             for ( CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  1897.                     iter.IsNotComplete(); frameProxy = (CEmbeddedFrameProxy*)iter.Next())
  1898.             {
  1899.                 if (frameProxy->IsAttached(ev))
  1900.                     frameProxy->Detach(ev);    
  1901.             }
  1902.         }
  1903.     }
  1904.  
  1905.     
  1906. }
  1907.  
  1908.  
  1909. //----------------------------------------------------------------------------------------
  1910. // CEmbeddingShape::Activate
  1911. // An (de)activate, suspend, or resume event has occured. Change the highlight state of
  1912. // corresponding facets' highlight state to reflect the change in active state.
  1913. //----------------------------------------------------------------------------------------
  1914.  
  1915. void CEmbeddingShape::Activate(Environment* ev, ODBoolean activating, ODFrame* frame)
  1916. {
  1917.     ODFacet* tFacet = this->GetEmbeddedFacet(ev, frame);
  1918.  
  1919.     ODHighlight highlight;
  1920.     if ( this->IsSelected() && activating ) highlight = kODFullHighlight;
  1921.     else if ( this->IsSelected() && !activating ) highlight = kODDimHighlight;
  1922.     else highlight = kODNoHighlight;
  1923.     
  1924.     ::ChangeFacetHighlight(ev, tFacet, highlight);
  1925. }
  1926.  
  1927.  
  1928. //------------------------------------------------------------------------------
  1929. // CEmbeddingShape::Resize
  1930. //------------------------------------------------------------------------------
  1931. void CEmbeddingShape::Resize(Environment *ev, Rect& baseRect, Rect& resizeRect)
  1932. {
  1933.     CRectangleShape::Resize(ev, baseRect, resizeRect);
  1934.     
  1935.     ODRect        odResizeRect(fRect);
  1936.     
  1937.     // Iterate over FrameProxies and resize each of them.
  1938.     COrdListIterator iter(fFrameProxies);
  1939.     for ( CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  1940.             iter.IsNotComplete(); frameProxy = (CEmbeddedFrameProxy*)iter.Next())
  1941.     {
  1942.         frameProxy->ResizeFrame(ev, odResizeRect);
  1943.     }
  1944.  
  1945. }
  1946.  
  1947.  
  1948. //------------------------------------------------------------------------------
  1949. // CEmbeddingShape::GetEmbeddedFacet
  1950. //------------------------------------------------------------------------------
  1951.  
  1952. ODFacet* CEmbeddingShape::GetEmbeddedFacet(Environment *ev, ODFacet* containingFacet)
  1953. {    
  1954.     ODFacet* embeddedFacet = kODNULL;
  1955.     
  1956.     // Proxy Iterator
  1957.     COrdListIterator iter(fFrameProxies);
  1958.     
  1959.     // Iterate over all the proxies to locate the one belonging to the given parent
  1960.     CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  1961.     do
  1962.     {
  1963.         // Check all facets 
  1964.         ODFrameFacetIterator* iter2 = frameProxy->GetFrame(ev)->CreateFacetIterator(ev);
  1965.         for (ODFacet* facet = iter2->First(ev); iter2->IsNotComplete(ev); facet = iter2->Next(ev))
  1966.         {
  1967.             
  1968.             if (facet->GetContainingFacet(ev)->GetFrame(ev) == 
  1969.                     containingFacet->GetFrame(ev))
  1970.             {
  1971.                 embeddedFacet = facet;
  1972.             }
  1973.         }
  1974.         frameProxy = (CEmbeddedFrameProxy*)iter.Next();
  1975.     } while (iter.IsNotComplete() && !embeddedFacet);
  1976.     return embeddedFacet;
  1977. }
  1978.  
  1979. //------------------------------------------------------------------------------
  1980. // CEmbeddingShape::GetEmbeddedFacet
  1981. //------------------------------------------------------------------------------
  1982.  
  1983. ODFacet* CEmbeddingShape::GetEmbeddedFacet(Environment* ev, ODFrame* containingFrame)
  1984. {    
  1985.     ODFacet* embeddedFacet = kODNULL;
  1986.     
  1987.     // Proxy Iterator
  1988.     COrdListIterator iter(fFrameProxies);
  1989.     
  1990.     // Iterate over all the proxies to locate the one belonging to the given parent
  1991.     CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  1992.     do
  1993.     {
  1994.         // Check all facets 
  1995.         ODFrameFacetIterator* iter2 = frameProxy->GetFrame(ev)->CreateFacetIterator(ev);
  1996.         for (ODFacet* facet = iter2->First(ev); iter2->IsNotComplete(ev); facet = iter2->Next(ev))
  1997.         {
  1998.             
  1999.             if (facet->GetContainingFacet(ev)->GetFrame(ev) == 
  2000.                     containingFrame)
  2001.             {
  2002.                 embeddedFacet = facet;
  2003.             }
  2004.         }
  2005.         frameProxy = (CEmbeddedFrameProxy*)iter.Next();
  2006.     } while (iter.IsNotComplete() && !embeddedFacet);
  2007.     return embeddedFacet;
  2008. }
  2009.  
  2010. //------------------------------------------------------------------------------
  2011. // CEmbeddingShape::GetAnyFrame
  2012. // Sometimes OpenDoc just wants a frame. So, this method will return the first
  2013. // embedded frame ( in memory ) found for "this" shape. kODNULL is returned
  2014. // if no frames are in memory.
  2015. //------------------------------------------------------------------------------
  2016.  
  2017. ODFrame* CEmbeddingShape::GetAnyFrame(Environment *ev)
  2018. {    
  2019.     ODFrame* embeddedFrame = kODNULL;
  2020.     
  2021.     // Iterate over all the proxies to locate the one belonging to the given parent
  2022.         // Proxy Iterator
  2023.         COrdListIterator iter(fFrameProxies);
  2024.         
  2025.         // Iterate over all the proxies to locate the one belonging to the given parent
  2026.         for (CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First(); 
  2027.                 iter.IsNotComplete(); 
  2028.                 frameProxy = (CEmbeddedFrameProxy*)iter.Next())
  2029.         {
  2030.             // If frameProxy's frame is loaded, return it
  2031.             if (frameProxy->IsFrameInMemory())
  2032.             {
  2033.                 return frameProxy->GetFrame(ev);
  2034.             }
  2035.         }
  2036.     
  2037.     return kODNULL;
  2038. }
  2039.  
  2040. //------------------------------------------------------------------------------
  2041. // CEmbeddingShape::ContainsProxyForFrame
  2042. //
  2043. // This method should return kODTrue if the given frame is embedded within this
  2044. // item of content. 
  2045. //
  2046. // NOTE: Does not cause load of frame.
  2047. //------------------------------------------------------------------------------
  2048.  
  2049. ODBoolean CEmbeddingShape::ContainsProxyForFrame(Environment* ev, ODFrame* frame)
  2050. {
  2051.     // Iterate over all the proxies to locate the one belonging to the given parent
  2052.     COrdListIterator iter(fFrameProxies);
  2053.     for (CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First(); 
  2054.             iter.IsNotComplete(); 
  2055.             frameProxy = (CEmbeddedFrameProxy*)iter.Next())
  2056.     {
  2057.         if (frame->GetID(ev) == frameProxy->GetFrameID())
  2058.             return kODTrue;
  2059.     }
  2060.     
  2061.     // Did not find a match
  2062.     return kODFalse;
  2063. }
  2064.  
  2065.  
  2066. //------------------------------------------------------------------------------
  2067. // CShape::SetInLimbo
  2068. //
  2069. //------------------------------------------------------------------------------
  2070.  
  2071. void CEmbeddingShape::SetInLimbo(Environment* ev, ODBoolean isInLimbo)
  2072. {
  2073.     // Notify all of our proxies of limbo status. See limbo discussion
  2074.     // in the programmers guide for more details.
  2075.     COrdListIterator iter(fFrameProxies);
  2076.     for ( CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  2077.             iter.IsNotComplete(); frameProxy = (CEmbeddedFrameProxy*)iter.Next())
  2078.     {
  2079.         frameProxy->SetInLimbo(ev, isInLimbo);
  2080.     }
  2081. }
  2082.  
  2083.  
  2084.  
  2085. //------------------------------------------------------------------------------
  2086. // CEmbeddingShape::OffsetShape
  2087. //------------------------------------------------------------------------------
  2088.  
  2089. void CEmbeddingShape::OffsetShape(Environment* ev, ODCoordinate xDelta, ODCoordinate yDelta)
  2090. {    
  2091.     CRectangleShape::OffsetShape(ev, xDelta, yDelta);
  2092.  
  2093.     ODPoint offset(xDelta, yDelta);
  2094.     
  2095.     // Iterate over all the proxies to locate the one belonging to the given parent
  2096.     // Iterate over all proxy frames and offset them
  2097.     COrdListIterator iter(fFrameProxies);
  2098.     for ( CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  2099.             iter.IsNotComplete(); frameProxy = (CEmbeddedFrameProxy*)iter.Next())
  2100.     {
  2101.         frameProxy->OffsetFrame(ev, offset);
  2102.     }
  2103. }
  2104.  
  2105.  
  2106.  
  2107. //----------------------------------------------------------------------------------------
  2108. // CEmbeddingShape::Removed
  2109. // This method is called to remove a frame from the document. If the commit flag is false
  2110. // then the shape will merely be detached with the assumption that the shape will be later
  2111. // re-added. If the commit flag is true, then the shape will PERMANENTLY be removed. That
  2112. // is to say, the frame will be removed from the parts embedded frame list, the Remove
  2113. // method will be called on the frame ( notifiying OD that the frame should be dismantled.
  2114. // 
  2115. //----------------------------------------------------------------------------------------
  2116.  
  2117. void CEmbeddingShape::Removed(Environment* ev, ODBoolean commit)
  2118. {
  2119.     CRectangleShape::Removed(ev, commit);
  2120.     
  2121.     // Iterate over all the proxies to locate the one belonging to the given parent
  2122.     COrdListIterator iter(fFrameProxies);
  2123.     for ( CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  2124.             iter.IsNotComplete(); frameProxy = (CEmbeddedFrameProxy*)iter.Next())
  2125.     {
  2126.         // Remove the shape ( frame ) from the visual hierarchy
  2127.         if (frameProxy->IsAttached(ev))
  2128.             frameProxy->Detach(ev);    
  2129.             
  2130.         if (commit)
  2131.         {
  2132.             frameProxy->RemoveAndPurge(ev);
  2133.         }    
  2134.     }
  2135. }
  2136.  
  2137.  
  2138. //----------------------------------------------------------------------------------------
  2139. // CEmbeddingShape::Added
  2140. //----------------------------------------------------------------------------------------
  2141.  
  2142. void CEmbeddingShape::Added(Environment *ev)
  2143. {
  2144.     CRectangleShape::Added(ev);
  2145.     
  2146.     // Add the shape ( frame ) to the document
  2147.     this->SetInLimbo(ev, kODFalse);
  2148. }
  2149.  
  2150.  
  2151. //----------------------------------------------------------------------------------------
  2152. // CEmbeddingShape::Open
  2153. //
  2154. // This method is called by the part when the user has selected "Open" for a selection.
  2155. // This will probably be only overridden by the proxy derivatives of shape.
  2156. //----------------------------------------------------------------------------------------
  2157. void CEmbeddingShape::Open(Environment *ev, ODFrame* container)
  2158. {
  2159.     // Use the embedded frame for the provided container 
  2160.     ODFrame* tFrame = this->GetEmbeddedFacet(ev, container)->GetFrame(ev);
  2161.     
  2162.     // tell the part to open
  2163.     ODPart*     tPart = tFrame ? tFrame->AcquirePart(ev) : kODNULL;
  2164.     if (tPart)
  2165.     {
  2166.         tPart->Open(ev, tFrame);
  2167.         
  2168.         ODReleaseObject(ev, tPart);
  2169.     }
  2170. }
  2171.  
  2172.  
  2173. //----------------------------------------------------------------------------------------
  2174. // CEmbeddingShape::DisplayFrameConnected
  2175. //
  2176. // This method is called by the part when a document is loaded and one of its display 
  2177. // frames has been internalized from storage and "connected" into the frame hierarchy.
  2178. // When this happens, we must execute the below special case code to make sure that our
  2179. // embedded content is re-internalized correctly.
  2180. //----------------------------------------------------------------------------------------
  2181.  
  2182. void CEmbeddingShape::DisplayFrameConnected(Environment *ev, ODFrame* frame)
  2183. {
  2184.     // SPECIAL CASE: In the case where a document was saved with embedded content AND then
  2185.     // dragged into a container which only clones the root part and does not use the root
  2186.     // frame for the document. In this case we must assume that any orphaned frame proxies
  2187.     // belong to the frame being added, and therefore attach the given frame to the orphaned
  2188.     // proxy frames. It is possible that there may have been multiple saved ( persistent )
  2189.     // display frames. That being the case, we will return as soon as we find 1 orphaned
  2190.     // proxy ( after having re-attached it to the passed in dispaly frame ). This way, if there
  2191.     // were multiple display frames saved, each one will get a proxy as it is internalized.
  2192.     // I can't guarantee correct restoration of ordering ( proxy to frame ), but that shouldn't
  2193.     // be important ( famous last words ).
  2194.     
  2195.     COrdListIterator iter(fFrameProxies);
  2196.     for ( CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  2197.             iter.IsNotComplete(); frameProxy = (CEmbeddedFrameProxy*)iter.Next())
  2198.     {
  2199.         if (frameProxy->IsOrphaned())
  2200.         {
  2201.             frameProxy->SetContainingFrame(ev, frame->GetID(ev));
  2202.             return;
  2203.         }
  2204.     }
  2205. }
  2206.  
  2207.  
  2208. //----------------------------------------------------------------------------------------
  2209. // CEmbeddingShape::DisplayFrameAdded
  2210. //
  2211. // This method is called by the part whenever a new display frame is added to the 
  2212. // container part. We must create a new embedded frame for this new container frame so
  2213. // that this shape will be displayed correctly in that new frame.
  2214. //----------------------------------------------------------------------------------------
  2215.  
  2216. void CEmbeddingShape::DisplayFrameAdded(Environment *ev, ODFrame* frame)
  2217. {
  2218.     // Find the part that this shape is 'wrapping'
  2219.     ODPart* embeddedPart = kODNULL;
  2220.  
  2221.     if (fFrameProxies->Count()==0)
  2222.     {
  2223.         // Can we add a containing frame to a shape with no proxies? 
  2224.         // DCS $$$$$
  2225.         DebugStr("\pCan't add frame to shape, there are no proxies.");
  2226.     }
  2227.     
  2228.     // Scan proxies. If we have an orphaned proxy, attach it to the given frame, otherwise
  2229.     // Try to access a part reference with which we can create a new proxy for the given
  2230.     // frame.    
  2231.     COrdListIterator iter(fFrameProxies); 
  2232.     CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  2233.     do
  2234.     {
  2235.         if (frameProxy->IsOrphaned())
  2236.         {
  2237.             // See special case comment in CEmbeddingShape::DisplayFrameConnected above.
  2238.             frameProxy->SetContainingFrame(ev, frame->GetID(ev));
  2239.             return;
  2240.         }
  2241.         else
  2242.         if (frameProxy->IsFrameInMemory())
  2243.         {
  2244.             embeddedPart = frameProxy->GetFrame(ev)->AcquirePart(ev);
  2245.         }
  2246.     
  2247.         
  2248.         frameProxy = (CEmbeddedFrameProxy*)iter.Next();
  2249.     } while (iter.IsNotComplete()&&!embeddedPart);
  2250.     
  2251.     if (embeddedPart)
  2252.     {
  2253.         // Make a proxy for the frame
  2254.         frameProxy = new CEmbeddedFrameProxy();
  2255.         frameProxy->InitializeEmbeddedFrameProxy(ev, 
  2256.                                     fDrawEditor, 
  2257.                                     this, 
  2258.                                     frame, 
  2259.                                     embeddedPart);
  2260.     
  2261.         // Add to our list of frameProxies
  2262.         this->AddFrameProxy(frameProxy);
  2263.         
  2264.         // Release acquired part
  2265.         ODReleaseObject(ev, embeddedPart);
  2266.     }
  2267. }
  2268.  
  2269.  
  2270.  
  2271. //----------------------------------------------------------------------------------------
  2272. // CEmbeddingShape::DisplayFrameRemoved
  2273. //
  2274. // This method is called by the part when a display frame is removed.
  2275. // This allows us to add a facet to the embedded frame wrapped by this shape.
  2276. //----------------------------------------------------------------------------------------
  2277.  
  2278. void CEmbeddingShape::DisplayFrameRemoved(Environment *ev, ODFrame* frame)
  2279. {    
  2280.     // I am assuming that there will be only one frame proxy for a given frame
  2281.     CEmbeddedFrameProxy* tProxy = kODNULL;
  2282.     
  2283.     // Iterate over all the proxies to locate the one belonging to the given parent
  2284.     COrdListIterator iter(fFrameProxies);
  2285.     for ( CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  2286.             iter.IsNotComplete(); frameProxy = (CEmbeddedFrameProxy*)iter.Next())
  2287.     {
  2288.         // ----- Remove the frame & proxy -----
  2289.         ODFrame* proxyContainer = frameProxy->AcquireContainingFrame(ev);
  2290.         if (proxyContainer==frame)
  2291.         {
  2292.             tProxy = frameProxy;
  2293.             ODFrame* embeddedFrame = tProxy->GetFrame(ev);
  2294.         
  2295.             // Remove abandoned frame proxy from our list
  2296.             // Shouldn't call GetFrame after this.        
  2297.             tProxy->Detach(ev);
  2298.         
  2299.             /// ODFrame::Remove calls release
  2300.             tProxy->RemoveAndPurge(ev);
  2301.         }
  2302.         
  2303.         // Release acquired container frame
  2304.         ODReleaseObject(ev, proxyContainer);
  2305.     }
  2306.     // Remove proxy from this shape's list then delete it.
  2307.     fFrameProxies->Remove(tProxy);
  2308.     delete tProxy;
  2309. }
  2310.  
  2311.  
  2312.  
  2313. //----------------------------------------------------------------------------------------
  2314. // CEmbeddingShape::DisplayFrameClosed
  2315. //
  2316. // This method is called by the part when a display frame is removed.
  2317. // This allows us to add a facet to the embedded frame wrapped by this shape.
  2318. //----------------------------------------------------------------------------------------
  2319.  
  2320. void CEmbeddingShape::DisplayFrameClosed(Environment *ev, ODFrame* frame)
  2321. {    
  2322.     // I am assuming that there will be only one frame proxy for a given frame
  2323.     CEmbeddedFrameProxy* tProxy = kODNULL;
  2324.     
  2325.     // Iterate over all the proxies to locate the one belonging to the given parent
  2326.     COrdListIterator iter(fFrameProxies);
  2327.     for ( CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  2328.             iter.IsNotComplete(); frameProxy = (CEmbeddedFrameProxy*)iter.Next())
  2329.     {
  2330.         // ----- Remove the frame & proxy -----
  2331.         ODFrame* proxyContainer = frameProxy->AcquireContainingFrame(ev);
  2332.         if (proxyContainer==frame)
  2333.         {
  2334.             tProxy = frameProxy;
  2335.             ODFrame*  embeddedFrame = tProxy->GetFrame(ev);
  2336.         
  2337.             // Remove abandoned frame proxy from our list    
  2338.             // Don't call GetFrame on the proxy after this.    
  2339.             tProxy->Detach(ev);
  2340.         
  2341.             // Tell OD to remove the frame, clear the proxy's structure.
  2342.             tProxy->CloseAndPurge(ev);
  2343.         }
  2344.         
  2345.         // Release acquired container frame
  2346.         ODReleaseObject(ev, proxyContainer);
  2347.     }
  2348.     // Remove proxy from this shape's list, then delete it
  2349.     // Must remove & delete outside of iteration to avoid confusing iterator
  2350.     fFrameProxies->Remove(tProxy);
  2351.     delete tProxy;
  2352. }
  2353.  
  2354.  
  2355. //----------------------------------------------------------------------------------------
  2356. // CEmbeddingShape::Dragging
  2357. //
  2358. // This method is called by the part when a the user is or was dragging this shape.
  2359. // Notify the embedded frame of the state of dragging.
  2360. //----------------------------------------------------------------------------------------
  2361.  
  2362. void CEmbeddingShape::Dragging(Environment *ev, ODBoolean dragging)
  2363. {
  2364.     // Notify all of our proxies.
  2365.     COrdListIterator iter(fFrameProxies);
  2366.     for ( CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  2367.             iter.IsNotComplete(); frameProxy = (CEmbeddedFrameProxy*)iter.Next())
  2368.     {
  2369.         ODFrame* frame = frameProxy->GetFrame(ev);
  2370.         frame->SetDragging(ev, dragging);
  2371.     }
  2372. }
  2373.  
  2374.  
  2375.  
  2376.  
  2377. //----------------------------------------------------------------------------------------
  2378. // CEmbeddingShape::FacetAdded
  2379. //
  2380. // This method is called by the part when a new containing facet is added.
  2381. // This allows us to add a facet to the embedded frame wrapped by this shape.
  2382. //----------------------------------------------------------------------------------------
  2383.  
  2384. void CEmbeddingShape::FacetAdded(Environment *ev, ODFacet* facet)
  2385. {
  2386.     // Iterate over all the proxies to locate the one belonging to the given parent
  2387.     COrdListIterator iter(fFrameProxies);
  2388.     for ( CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  2389.             iter.IsNotComplete(); frameProxy = (CEmbeddedFrameProxy*)iter.Next())
  2390.     {
  2391.         // ----- Add facets to the frame being proxy, IF the frame is in memory -----
  2392.         
  2393.         if (frameProxy->IsFrameInMemory())
  2394.         {
  2395.             ODFrame* facetContainer = facet->GetFrame(ev);
  2396.             ODFrame* proxyContainer = frameProxy->AcquireContainingFrame(ev);
  2397.             if (facetContainer==proxyContainer)
  2398.             {
  2399.                 frameProxy->CreateFacetsForContainer(ev, facet);
  2400.             }
  2401.             
  2402.             // Set the hilight state of the embedded facet
  2403.             ODFacet* tFacet = GetEmbeddedFacet(ev, facet);
  2404.             
  2405.             ODHighlight highlight;
  2406.             ODBoolean active = facet->GetWindow(ev)->IsActive(ev);
  2407.         
  2408.             if ( this->IsSelected() && active ) highlight = kODFullHighlight;
  2409.             else if ( this->IsSelected() && !active ) highlight = kODDimHighlight;
  2410.             else highlight = kODNoHighlight;
  2411.             
  2412.             tFacet->SetSelected(ev, this->IsSelected());
  2413.             ::ChangeFacetHighlight(ev, tFacet, highlight);
  2414.             
  2415.             // Release acquired container frame
  2416.             ODReleaseObject(ev, proxyContainer);
  2417.         }
  2418.     }
  2419. }
  2420.  
  2421.  
  2422.  
  2423. //----------------------------------------------------------------------------------------
  2424. // CEmbeddingShape::FacetRemoved
  2425. //
  2426. // This method is called by the part when a containing facet is removed.
  2427. // This allows us to remove the facet contained by the facet that is removed.
  2428. //----------------------------------------------------------------------------------------
  2429.  
  2430. void CEmbeddingShape::FacetRemoved(Environment *ev, ODFacet* facet)
  2431. {
  2432.     // Iterate over all the proxies to locate the one belonging to the given parent
  2433.     COrdListIterator iter(fFrameProxies);
  2434.     for ( CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  2435.             iter.IsNotComplete(); frameProxy = (CEmbeddedFrameProxy*)iter.Next())
  2436.     {
  2437.         // ----- Remove the frame & proxy -----
  2438.         ODFrame* facetContainer = facet->GetFrame(ev);
  2439.         ODFrame* proxyContainer = frameProxy->AcquireContainingFrame(ev);
  2440.         if (facetContainer==proxyContainer)
  2441.         {
  2442.             frameProxy->RemoveFacetsForContainer(ev, facet);
  2443.         }
  2444.         
  2445.         // Release acquired container frame
  2446.         ODReleaseObject(ev, proxyContainer);
  2447.     }
  2448. }
  2449.  
  2450.  
  2451.  
  2452. //------------------------------------------------------------------------------
  2453. // CEmbeddingShape::Read
  2454. // We assume that the storage unit is focused to a property and value and
  2455. // that the current offset is the beginning of a shape.
  2456. //------------------------------------------------------------------------------
  2457.  
  2458. void CEmbeddingShape::Read(Environment* ev, ODStorageUnitView* view, CCloneInfo* cloneInfo)
  2459. {
  2460.     CEmbeddingShape::Read(ev, view->GetStorageUnit(ev), cloneInfo);
  2461. }
  2462.  
  2463.  
  2464. //------------------------------------------------------------------------------
  2465. // CEmbeddingShape::Read
  2466. // We assume that the storage unit is focused to a property and value and
  2467. // that the current offset is the beginning of a shape.
  2468. //------------------------------------------------------------------------------
  2469.  
  2470. void CEmbeddingShape::Read(Environment* ev, ODStorageUnit* storage, CCloneInfo* cloneInfo)
  2471. {
  2472.     CRectangleShape::Read(ev, storage, cloneInfo);
  2473.     
  2474.     /// Read the number of proxies
  2475.     ODULong proxyCount;
  2476.     StorageUnitGetValue(storage, ev, sizeof(ODULong), &proxyCount);
  2477.     
  2478.     // Read in the proxies
  2479.     for (ODULong index = 0; index < proxyCount; index++)
  2480.     {
  2481.         // Make a proxy
  2482.         CEmbeddedFrameProxy* frameProxy = new CEmbeddedFrameProxy();
  2483.         frameProxy->InitializeEmbeddedFrameProxy(ev, fDrawEditor, this);
  2484.             
  2485.         if (frameProxy->Read(ev, storage, cloneInfo))
  2486.         {
  2487.             this->AddFrameProxy(frameProxy);
  2488.         }
  2489.         else
  2490.             THROW(kODErrInvalidStorageUnitRef);
  2491.     }
  2492.             
  2493. }
  2494.  
  2495.  
  2496. //------------------------------------------------------------------------------
  2497. // CEmbeddingShape::Write
  2498. // We assume that the storage unit is focused to a property and value and
  2499. // that the current offset is a good place to write out a shape.
  2500. //------------------------------------------------------------------------------
  2501.  
  2502. void CEmbeddingShape::Write(Environment* ev, ODStorageUnitView* view, CCloneInfo* cloneInfo)
  2503. {
  2504.     this->Write(ev, view->GetStorageUnit(ev), cloneInfo);
  2505. }
  2506.  
  2507.  
  2508. //------------------------------------------------------------------------------
  2509. // CEmbeddingShape::Write
  2510. // We assume that the storage unit is focused to a property and value and
  2511. // that the current offset is a good place to write out a shape.
  2512. //------------------------------------------------------------------------------
  2513.  
  2514. void CEmbeddingShape::Write(Environment* ev, ODStorageUnit* storage, CCloneInfo* cloneInfo)
  2515. {
  2516.     CRectangleShape::Write(ev, storage, cloneInfo);
  2517.     
  2518.     /// Write the number of proxies
  2519.     ODULong proxyCount = fFrameProxies->Count();
  2520.     StorageUnitSetValue(storage, ev, sizeof(ODULong), &proxyCount);
  2521.     
  2522.     // Write out the proxies contained by the scope ( source of copy ) frame
  2523.     // specified in the cloneInfo
  2524.     
  2525.     
  2526.     // Iterate over all the proxies to locate the one belonging to the given parent
  2527.     COrdListIterator iter(fFrameProxies);
  2528.     for ( CEmbeddedFrameProxy* frameProxy = (CEmbeddedFrameProxy*)iter.First();
  2529.             iter.IsNotComplete(); frameProxy = (CEmbeddedFrameProxy*)iter.Next())
  2530.     {
  2531.         ODFrame* containingFrame = frameProxy->AcquireContainingFrame(ev);
  2532.         
  2533.         // If we are cloning, then write only in the case where there is
  2534.         // no scope frame or the proxy falls within the scope frame. 
  2535.         // Write if we are not doing a clone, as well.
  2536.         if (cloneInfo && cloneInfo->fScopeFrame==kODNULL)
  2537.             frameProxy->Write(ev, storage, cloneInfo);
  2538.         else
  2539.         if (cloneInfo && containingFrame==cloneInfo->fScopeFrame)
  2540.             frameProxy->Write(ev, storage, cloneInfo);
  2541.         else
  2542.         if (cloneInfo==kODNULL)
  2543.             frameProxy->Write(ev, storage, cloneInfo);
  2544.             
  2545.         // Release acquired frame
  2546.         ODReleaseObject(ev, containingFrame);
  2547.     }
  2548. }
  2549.  
  2550. //------------------------------------------------------------------------------
  2551. // CEmbeddingShape::Publish
  2552. //------------------------------------------------------------------------------
  2553.  
  2554. void CEmbeddingShape::Publish(Environment* ev, CPublishLink* link)
  2555. {
  2556.     CShape::Publish (ev, link);
  2557.     
  2558.     if (fPublishLinks->Count() == 1)
  2559.         this->ChangeLinkStatus(ev, kODInLinkSource);
  2560.         
  2561. }
  2562.  
  2563.  
  2564. //------------------------------------------------------------------------------
  2565. // CEmbeddingShape::ChangeLinkStatus
  2566. //------------------------------------------------------------------------------
  2567.  
  2568. void CEmbeddingShape::ChangeLinkStatus(Environment* ev, ODLinkStatus linkStatus)
  2569. {
  2570.  
  2571.     //  This is the way we've been doing it in ODFDrawLink, but ask *
  2572.     // if it's really necessary to do this to each frame. Does each frame as its
  2573.     // status is changed, then call the same part's LinkStatusChanged *again*?
  2574.     
  2575.     COrdListIterator iter(fFrameProxies);
  2576.     for (CEmbeddedFrameProxy* proxy = (CEmbeddedFrameProxy*)iter.First(); iter.IsNotComplete(); proxy = (CEmbeddedFrameProxy*)iter.Next())
  2577.         proxy->GetFrame(ev)->ChangeLinkStatus(ev, linkStatus);    
  2578. }
  2579.  
  2580. #pragma segment Main
  2581. void CEmbeddingShape::Subscribe(Environment* ev, CSubscribeLink* link)
  2582. {
  2583.     CRectangleShape::Subscribe(ev, link);
  2584.     
  2585.     this->ChangeLinkStatus(ev, kODInLinkDestination);
  2586. }
  2587.  
  2588. #pragma segment Main
  2589. void  CEmbeddingShape::Unpublish(Environment* ev, CPublishLink* link)
  2590. {
  2591.     CShape::Unpublish (ev, link);
  2592.     
  2593.     if (fPublishLinks->Count() == 0)
  2594.         this->ChangeLinkStatus(ev, kODNotInLink);
  2595.         
  2596. }
  2597.  
  2598.  
  2599. #pragma segment Main
  2600. void CEmbeddingShape::Unsubscribe(Environment* ev)
  2601. {    
  2602.     CShape::Unsubscribe(ev);
  2603.     
  2604.     if (fPublishLinks->Count() != 0)
  2605.         this->ChangeLinkStatus(ev, kODInLinkSource);
  2606.     else
  2607.         this->ChangeLinkStatus(ev, kODNotInLink);
  2608.         
  2609. }
  2610.  
  2611.  
  2612.  
  2613.  
  2614.  
  2615.  
  2616.